﻿////////////////////////////////////////////////////////////////////////////////
//
// Arp Rich Internet Application Framework (http://osflash.org/arp)
// Copyright © 2004-2006 Aral Balkan (http://flashant.org)
//
// Released under the open-source MIT license.
// (http://www.opensource.org/licenses/mit-license.php)
//
// See license.txt for full license terms.
//
////////////////////////////////////////////////////////////////////////////////

import org.osflash.arp.log.Log;
import mx.validators.*;

/**
* <p><b>Base class for creating popup forms with validation.</b></p>
* 
* <p>Includes simple ActionScript-based validation routines that don't require 
* the placement of code in MXML (Validator tags, Model tags or binding.)</p>
* 
* <p>Author: Darron Schall (based on FlexApplication by Aral Balkan)</p>
*
* <p><i>Copyright &copy; 2004-2006 <a href="http://flashant.org">Aral Balkan</a>.
* Arp lives at <a href="http://osflash.org/arp">http://osflash.org/arp</a>. 
* getPreferredHeight/Width overrides by Darron Schall.
* 
* Released under the open-source MIT license.
* (http://www.opensource.org/licenses/mit-license.php)
* See license.txt for full license terms.</i></p>
*/
class org.osflash.arp.FlexPopUp extends mx.containers.TitleWindow
{
	//////////////////////////////////////////////////////////////////////
	//
	// Properties
	//
	//////////////////////////////////////////////////////////////////////

	private var warningsOn:Boolean = true;
	
	/** 
	* Overwrite this property in your form if you want 
	* logging to be turned on.
	*/
	private var showLog:Boolean = false;
	

	//////////////////////////////////////////////////////////////////////
	//
	// Constructor
	//
	//////////////////////////////////////////////////////////////////////
	function FlexPopUp ()
	{
		//
		// Initialize the LuminicBox logger
		//
		
		// Store the setting so that turning off logging in the core
		// application form for an application with external screens
		// turns off logging for all subsequent screents too.
		if ( !showLog ) { Log.showLog = false; };
		 
		if ( Log.showLog )
		{
			Log.initialize();
		}
						
		// We don't do anything in the constructor that involves child
		// components or forms since they may not have initialized
		// yet. Instead we carry out all such actions in the childrenCreated() 
		// event handler. 
				
		// You can override the constructor in your form and
		// initialize complex members here.		
	}
	
	//////////////////////////////////////////////////////////////////////
	//
	// Public methods
	//
	//////////////////////////////////////////////////////////////////////
		
	// None
	
	//////////////////////////////////////////////////////////////////////
	//
	// Group: Private methods
	//
	//////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////
	//
	// Method: addValidationListeners()
	//
	// Override this method and use it to add the validateForm() method
	// as a listener to those components that you want to validate.
	//
	// eg. 
	//
	// 	mailTextInput.addEventListener ( "change", Delegate.create ( this, validateForm ) );
	//	passwordTextInput.addEventListener ( "change", Delegate.create ( this, validateForm ) );	
	//
	//////////////////////////////////////////////////////////////////////
	private function addValidationListeners ():Void
	{
		// Warn if not overriden
		if ( warningsOn )
		{
			Log.warn ( "FlexPopUp.addValidationListeners() not overriden in " + this );
		}
	}
	
	//////////////////////////////////////////////////////////////////////
	//
	// Method: addValidators()
	//
	// Override this method and use it to add validators for this form
	// by calling the addValidator() method.
	//
	// eg. addValidator ( StringValidator, this, "passwordTextInput", 
	//                    "text", { minLength:4 } );		
	//
	//////////////////////////////////////////////////////////////////////
	private function addValidators ():Void
	{
		// Warn if not overriden
		if ( warningsOn )
		{
			Log.warn ( "FlexPopUp.addValidators() not overriden in " + this );
		}
	}

	//////////////////////////////////////////////////////////////////////
	//
	// Method: setupValidation()
	//
	// Sets up validation for the form.
	//
	//////////////////////////////////////////////////////////////////////
	private function setupValidation ():Void
	{
		Log.info ( "FlexPopUp.setupValidation() on " + this );
	
		// Initialize for validator
		Validator._initForValidation(this);
	
		// Add listeners for validation triggers on components
		addValidationListeners();
		
		// Add validators for this form
		addValidators();
			
		// Optimize validators
		Validator._optimizeValidators(this);
	}
	
	//////////////////////////////////////////////////////////////////////
	//
	// Method: addValidator()
	//
	// Creates a new validator and adds it to the form
	//
	//////////////////////////////////////////////////////////////////////
	private function addValidator ( validatorClass:Function, formScope:Object, componentName:String, componentProperty:String, validatorArguments:Object ):Validator
	{
		var propertyNameString:String;
		if ( componentProperty != null )
		{
			propertyNameString = componentName + "." + componentProperty;
		}
		else
		{
			propertyNameString = componentName;
		}

		// Log.debug ( "addValidator" );
		// Log.debug ( validatorClass );
		// Log.debug ( "property name = " + propertyNameString );
		// Log.debug ( ">>> formScope = " + formScope );
		// Log.debug ( componentName );
		// Log.debug ( componentProperty );
		// Log.debug ( validatorArguments );

		var propertyFunction:Function = function () 
		{ 
			var activationObject:Function = arguments.callee;
			var property:Object = activationObject.formScope [ activationObject.componentName ] [ activationObject.componentProperty ];
		
			// org.osflash.arp.log.Log.it ( "**formScope = " + activationObject.formScope );
			// org.osflash.arp.log.Log.it ( "**componentName = " + activationObject.componentName );
			// org.osflash.arp.log.Log.it ( "**componentProperty = " + activationObject.componentProperty);
		
			return property; 
		};
		propertyFunction.formScope = formScope;
		propertyFunction.componentName = componentName;
		propertyFunction.componentProperty = componentProperty;
				
		var listenerFunction:Function = function () { return arguments.callee.listenerReference; };
		listenerFunction.listenerReference = formScope [ componentName ];
	
		var newValidator = new validatorClass();
		newValidator._init ( formScope, propertyNameString, propertyFunction, listenerFunction, validatorArguments );
				
		Validator._addValidator ( formScope, propertyNameString, newValidator );
		
		// Return a reference to the validator
		return newValidator;
	}

	//////////////////////////////////////////////////////////////////////
	//
	// Method: validateForm()
	//
	// Override this method and place your validation logic in here. eg.
	//
	// isFormValid = Validator.isValid ( this, "passwordTextInput.text" );
	// loginButton.enabled = isFormValid;
	//
	//////////////////////////////////////////////////////////////////////
	private function validateForm ():Boolean
	{
		if ( warningsOn )
		{
			Log.warn ( "FlexPopUp.validateForm() not overriden in " + this );
		}
		return false;
	}


	//////////////////////////////////////////////////////////////////////
	//
	// Event Handlers
	//
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	//
	// Method: init()
	//
	// Overrides init() method to listen for the childrenCreated event
	// (similar to onLoad in Flash.)
	//
	//////////////////////////////////////////////////////////////////////
	private function init():Void
	{
		// Make sure you call the superclass' constructor or the
		// component (this form) will not display correctly
		super.init();
		
		// Listen for childrenCreated so we know when to 
		// interact with out child forms and components.
		addEventListener ( "childrenCreated", this );
	}
	
	//////////////////////////////////////////////////////////////////////
	//
	// Method: childrenCreated()
	//
	// Setup validation and call the onLoad method. If you want to
	// override childrenCreated instead of using the provided onLoad
	// hook, make sure you call super.childrenCreated() on the first
	// line, otherwise validation will not be initialized for your form.
	//
	/////////////////////////////////////////////////////////////////////
	private function childrenCreated ():Void
	{
		// Setup validation
		setupValidation();

		// Proxy to helper method. Besides other things, this is to 
		// allow calls to super.onChildrenCreated(). 
		onChildrenCreated();
	}	

	//////////////////////////////////////////////////////////////////////
	//
	// Method: onChildrenCreated()
	//
	// Override this method in your form. In your overriden method, 
	// you can listen for view events, carry out child component 
	// initializations, etc.
	//
	/////////////////////////////////////////////////////////////////////
	private function onChildrenCreated ():Void
	{
		if ( warningsOn )
		{
			Log.warn ( "FlexPopUp.onChildrenCreated() not overriden in " + this );
		}
	}	
}